/*!
 Temelia - Hash Map interface.

 Copyright (C) 2008, 2009 Ceata (http://cod.ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef HASHSET_H_
#define HASHSET_H_

#include "platform.h"

struct _hash_map_t;
typedef struct _hash_map_t *hash_map_t;

/*!
 * @brief Constructor.
 * Complexity O(1)
 *
 * @return Empty hash map
 */
DECLSPEC hash_map_t hash_map_new(void);

/*!
 * @brief Clears hash map.
 * Complexity O(1)
 *
 * @param Hash map
 */
DECLSPEC void hash_map_clear(hash_map_t hash_map);

/*!
 * @brief Destructor. Frees the memory occupied by hash map.
 * Complexity O(n)
 *
 * @param Hash map
 */
DECLSPEC void hash_map_delete(hash_map_t hash_map);

/*!
 * @brief Checks if hash map contains key. Return 1 if it does, 0 if not
 * or -1 if an error occurred.
 * Complexity O(log(n))
 *
 * @param Hash map
 * @param Key
 * @param Pointer to keys comparison function
 * @param Comparison context
 */
DECLSPEC int hash_map_contains_key(hash_map_t hash_map, void *key, int compare(void *x,
		void *y, void *context), void *context);

/*!
 * @brief Checks if hash map contains value.
 * Complexity O(log(n))
 *
 * @param Hash map
 * @param Value
 * @param Pointer to values comparison function
 * @param Comparison context
 * @see hash_map_contains_key
 */
DECLSPEC int hash_map_contains_value(hash_map_t hash_map, void *value,
		int compare_values(void *x, void *y, void *context), void *context);

/*!
 * @brief Checks if hash map is empty
 * Complexity O(1)
 *
 * @param Hash map
 */
DECLSPEC int hash_map_is_empty(hash_map_t hash_map);

/*!
 * @brief Returns the size of hash map.
 * Complexity O(1)
 *
 * @param Hash map
 */
DECLSPEC int hash_map_get_size(hash_map_t hash_map);

/*!
 * @brief Adds pair (key, value) to hash map. If key is found then
 * it's value is actualized to "value".
 * Complexity O(log(n))
 *
 * @param Hash map
 * @param Key
 * @param Value
 * @param Pointer to keys comparison function
 * @return key's old value or NULL if it was not in this hash map
 */
DECLSPEC void *hash_map_put(hash_map_t hash_map, void *key, void *value,
		int compare_keys(void *x, void *y, void *context), void *context);

/*!
 * @brief Removes key from hash map and it's value.
 * Complexity O(log(n))
 *
 * @param Hash map
 * @param Key
 * @param Pointer to keys comparison function
 * @return 1 if success, 0 if not, -1 if an error occurred
 */
DECLSPEC int hash_map_remove_key(hash_map_t hash_map, void *key, int compare_keys(
		void *x, void *y, void *context), void *context);

/*!

 * @brief Removes value from hash map and it's key.
 * Complexity O(log(n))
 *
 * @param Hash map
 * @param Value
 * @param Pointer to values comparison function
 * @return 1 if success, 0 if not, -1 if an error occurred
 */
DECLSPEC int hash_map_remove_value(hash_map_t hash_map, void *value, int compare_values(
		void *x, void *y, void *context), void *context);

/*!
 * @brief Returns hash map internal representation; it's a root of red-black tree.
 * Complexity O(1)
 *
 * @param Hash map
 */
DECLSPEC void *hash_map_get_internal_representation(hash_map_t hash_map);

/*!
 * @brief Prints the content of hash map calling key_handler and value_handler for each
 * pair stored in this container
 * Complexity O(n)
 *
 * @param Hash map
 * @param Pointer to key handling function
 * @param Pointer to context
 */
DECLSPEC void hash_map_iterate_keys(hash_map_t hash_map, void handler(void *key,
		void *context), void *context);

/*!
 * @brief Prints the content of hash map calling key_handler and value_handler for each
 * pair stored in this container.
 * Complexity O(n)
 *
 * @param Hash map
 * @param Pointer to value handling function
 * @param Pointer to context
 */
DECLSPEC void hash_map_iterate_values(hash_map_t hash_map, void handler(void *value,
		void *context), void *context);

/*!
 * @brief Iterates over hash map and calls given handler with pairs (key, value).
 * Complexity O(n)
 *
 * @param Hash map
 * @param Pointer to handling function
 * @param Pointer to context
 */
DECLSPEC void hash_map_iterate(hash_map_t hash_map, void handler(void *key, void *value,
		void *context), void *context);

#endif /* HASHSET_H_ */
